<template>
  <div>
    <div class="main">
      <div class="overview">班级平均年龄：{{ avgAge }}</div>
      <div class="tools-header">
        <button class="openModalBtn" @click="addStudent">添加学生</button>
        <button class="openModalBtn" @click="delSelectedStudent">删除学生</button>
        <div>
          <input
            v-model="keyword"
            type="text"
            name="keyword"
            class="keyword"
            placeholder="Search by name"
          />
          <button type="button" class="searchBtn" @click="searchFunc">搜索</button>
        </div>
      </div>

      <table class="studentTable">
        <thead>
          <tr>
            <!-- 设置变量双向绑定；绑定改变事件定义方法 -->
            <th>
              <input
                v-model="isAllSelected"
                @change="changeSelectedAll"
                type="checkbox"
                class="selectAll"
              />
            </th>
            <th>ID</th>
            <th>Name</th>
            <th>Gender</th>
            <th>Hobbies</th>
            <th>Email</th>
            <th>Phone</th>
            <th>Age</th>
            <th>Created At</th>
            <th>Updated At</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody>
          <!-- Student rows will be added dynamically here -->
          <!-- 遍历的数组为查找的数组（渲染页面） -->
          <tr v-for="item in searchStudentArr" :key="item.id">
            <td>
              <!-- 设置变量双向绑定；绑定改变事件定义方法 -->
              <input
                v-model="item.selected"
                @change="changeSelectedItem"
                type="checkbox"
                class="selectAll"
              />
            </td>
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>
            <td>{{ item.gender }}</td>
            <td>{{ item.hobbies }}</td>
            <td>{{ item.email }}</td>
            <td>{{ item.phone }}</td>
            <td>{{ item.age }}</td>
            <td>{{ item.create_at }}</td>
            <td>{{ item.update_at }}</td>
            <td>
              <button @click="editStuInfo(item)" class="editBtn" type="button">修改</button>
              <button @click="deleteStuInfo(item)" class="deleteBtn" type="button">删除</button>
            </td>
          </tr>
        </tbody>
      </table>

      <!-- Modal for adding/editing students -->
      <div v-show="isShowModel" class="studentModal modal" @click="closeModel">
        <!-- click.stop 阻止冒泡 -->
        <div class="modal-content" @click.stop>
          <h3 class="modalTitle">{{ modelInfo.title }}</h3>
          <userInfoForm :userInfo='stuFormData' @save='saveStuInfo'></userInfoForm>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import { getNowDateTime } from '@/utils'

import { uniqueId } from 'lodash'
import userInfoForm from './components/userInfoForm.vue';
import { type IStudent } from './components/userInfoForm.vue'

// 控制模态框的显示隐藏
const isShowModel = ref(false)

// 模态框配置
const modelInfo = ref({
  type: 'add',
  title: '添加学生信息',
  clickBtn: '保存学生信息'
})

// 初始化表格数据
const stuFormData = ref<IStudent>({
  id: '',
  age: '',
  email: '',
  gender: '',
  hobbies: '',
  name: '',
  phone: ''
})

// 保存全量数据（增删改的数据都在这里修改）,这里不需要ref
const studentArr: Array<IStudent> = [
  {
    id: 'qnewStu_1',
    name: 'Alice',
    gender: 'Female',
    hobbies: 'Reading',
    email: 'alice@example.com',
    phone: '12345678901',
    age: 20,
    create_at: getNowDateTime(),
    update_at: getNowDateTime()
  },
  {
    id: 'qnewStu_2',
    name: 'Bob',
    gender: 'Male',
    hobbies: 'Sports',
    email: 'bob@example.com',
    phone: '10987654321',
    age: 22,
    create_at: getNowDateTime(),
    update_at: getNowDateTime()
  }
]

/**
 * 本地存储
 */
// const jsonStudentArr = JSON.stringify(studentArr)
// localStorage.setItem("studentData",jsonStudentArr)
// localStorage.getItem("studentData")
// localStorage.removeItem("studentData")
// localStorage.clear

/**
 * 本地存储存
 */
const setLocalValue = (key:string,value:string)=>{
  localStorage.setItem(key,value)
}
/**
 * 本地存储取
 */
const getLocalValue = (key:string):string=>{
  return JSON.parse(localStorage.getItem(key) as string)
}

const keyword = ref('')
const searchStudentArr = ref<Array<IStudent>>([])

/**
 * 检索数据
 */
// 1. 声明变量keyword,获取input的输入内容
// 2. 用全量数据筛选数据，赋值给搜索数据
// 3. 在列表中遍历搜索数据
// 4. 在保存学生信息方法、删除学生信息方法中调用；并在末尾初始化数据
const searchFunc = () => {
  searchStudentArr.value = studentArr.filter((i) => i.name.includes(keyword.value))
}

// 初始化数据
const initFunc = () => {
  searchFunc()
}

/**
 * 保存学生信息
 */
const saveStuInfo = (userInfo:IStudent) => {
  stuFormData.value = userInfo
  // 判断是修改还是添加
  if (modelInfo.value.type === 'add') {
    // 添加学生信息
    // 1.生成学生id
    // 2.把新的学生信息追加到学生数组中
    stuFormData.value.id = uniqueId('newStu_')
    console.log(stuFormData.value)
    // 用JSON把reactive的引用破解
    studentArr.push({
      ...JSON.parse(JSON.stringify(stuFormData.value)),
      create_at: getNowDateTime(),
      update_at: getNowDateTime()
    })
  } else {
    // 修改学生信息
    // 1. 查找匹配学生id
    // 2. 把新的学生信息修改替换到学生数组中
    stuFormData.value.update_at = getNowDateTime()
    // 修改学生信息
    const index = studentArr.findIndex((i) => i.id === stuFormData.value.id)
    studentArr[index] = JSON.parse(JSON.stringify(stuFormData.value))
  }
  searchFunc()
  changeSelectedItem()
}

/**
 * 添加学生信息
 */
const addStudent = () => {
  // 添加之前清空页面
  stuFormData.value = {
    id: '',
    age: '',
    email: '',
    gender: '',
    hobbies: '',
    name: '',
    phone: ''
  }
  modelInfo.value.type = 'add'
  modelInfo.value.title = '添加学生信息'
  modelInfo.value.clickBtn = '保存学生信息'
  isShowModel.value = true
}

/**
 * 修改学生信息
 */
const editStuInfo = (stu: IStudent) => {
  modelInfo.value.type = 'edit'
  modelInfo.value.title = '修改学生信息'
  modelInfo.value.clickBtn = '修改学生信息'
  // JSON拷贝 切断响应
  stuFormData.value = JSON.parse(JSON.stringify(stu))
  isShowModel.value = true
}

/**
 * 删除学生信息
 */
const deleteStuInfo = (stu: IStudent) => {
  // 1. 找到 id
  const indexDelete = studentArr.findIndex((student) => student.id === stu.id)
  studentArr.splice(indexDelete, 1)
  searchFunc()
  changeSelectedItem()
}

/**
 * 复选框删除学生
 */
// 通过复选框布尔值找到id,删除数组；调用渲染页面搜索数据更新页面
// 方法一：forEach遍历+findIndex索引+splice删除数组
const delSelectedStudent = () => {
  searchStudentArr.value.forEach((item) => {
    if (item.selected) {
      deleteStuInfo(item)
    }
  })
  searchFunc()
}

// 方法二：filter筛选数组+splice数组替换
// const delSelectedStudent = () => {
//   const updateArr = searchStudentArr.value.filter((item) => !item.selected)
//   studentArr.splice(0, studentArr.length, ...updateArr)
//   searchFunc()
// }

// 关闭模态框
const closeModel = () => {
  isShowModel.value = false
}

const isAllSelected = ref(false)
/**
 * 全选全不选
 */
const changeSelectedAll = (event: Event) => {
  const checked = (event.target as HTMLInputElement).checked
  if (checked) {
    // 给数组对象的属性赋值，先数组遍历属性（forEach）
    searchStudentArr.value.forEach((item) => {
      item.selected = true
    })
  } else {
    searchStudentArr.value.forEach((item) => {
      item.selected = false
    })
  }
}

const changeSelectedItem = () => {
  // 根据页面数组的长度是否为 0 来改变全选变量的值;并在保存信息和删除信息中调用
  if (searchStudentArr.value.length > 0) {
    // 子项全选才选中用every,返回的布尔值赋值给全选变量
    isAllSelected.value = searchStudentArr.value.every((i) => i.selected)
  } else {
    isAllSelected.value = false
  }
}

/**
 * 计算平均年龄
 */
// 注：页面清空时，avgAge为 0
const avgAge = computed(() => {
  return (
    Math.round(
      searchStudentArr.value.reduce(
        (previousValue, currentValue) => previousValue + Number(currentValue.age),
        0
      ) / searchStudentArr.value.length
    ) || 0
  )
})

initFunc()
</script>

<style lang="scss" scoped>
@import url('../../assets/reset.scss');
@import './style/demo1.scss';
</style>
